import hashlib
import friends
from utils import *

CMD_TYPE_GET = 0
CMD_TYPE_GETVER = 1
CMD_TYPE_RESP = 2
CMD_TYPE_ERR = 0xFF
CMD_RESP_CODE_OK = 0
CMD_RESP_CODE_NA = 1
CMD_RESP_CODE_NE = 2

class cmd:
    """cmd object prototype"""
    def __init__(self,type):
        """build a cmd object by type"""
        self._type = type
        self._senderID = None
        self._signature = None
    
    def getType(self):
        return self._type
    
    def setSenderID(self,senderID):
        self._senderID = senderID
        
    def getSenderID(self):
        return self._senderID
    
    def setSignature(self,signature):
        """signature should be a signature object"""
        self._signature = signature
        
    def getSignature(self):
        """return a signature object"""
        return self._signature
    
    def getSerializeNoSign(self):
        """return canonical string repr of command
        prototype"""
        return "%d;%s"%(self.getType(),self.getSenderID())
        return
    
    def checkSignature(self):
        """return True if signature OK"""
        #try to get the requester friend object
        requesterObject = friends.getGlobalAccount(self.getSenderID())
        try:
            #test if requester is already known
            key = requesterObject.getKey()
            #calculate digest of cmd
            digest = hashlib.sha1(self.getSerializeNoSign()).digest()
            #check signature
            if key.verify(digest,self.getSignature().getValue()):
                infoOutput("CHECK SIGN SUCCESS cmd (type:%d,requester:%s)"%(self.getType(),self.getSenderID()))
                return True
            else:
                warningOutput("SIGN CHECK ERROR cmd (type:%d,requester:%s)"%(self.getType(),self.getSenderID()))
                return False
        except accountError:
            warningOutput("requester (ID:%s) unknown"%(self.getSenderID(),))
            return False

    
class getCmd(cmd):
    def __init__(self):
        cmd.__init__(self,CMD_TYPE_GET)
        self._ID = None
        self._authorID = None
        
    def setID(self,ID):
        self._ID = ID
        
    def getID(self):
        return self._ID
    
    def setAuthorID(self,authorID):
        self._authorID = authorID
        
    def getAuthorID(self):
        return self._authorID
    
    def getSerializeNoSign(self):
        return "%d;%s;%s;%s"%(self.getType(),self.getID(),self.getAuthorID(),self.getSenderID())
    
class getVerCmd(cmd):
    def __init__(self):
        cmd.__init__(self,CMD_TYPE_GETVER)
        self._ID = None
        self._authorID = None
        
    def setID(self,ID):
        self._ID = ID
        
    def getID(self):
        return self._ID
    
    def setAuthorID(self,authorID):
        self._authorID = authorID
        
    def getAuthorID(self):
        return self._authorID
    
    def getSerializeNoSign(self):
        return "%d;%s;%s;%s"%(self.getType(),self.getID(),self.getAuthorID(),self.getSenderID())
    
class respCmd(cmd):
    def __init__(self):
        cmd.__init__(self,CMD_TYPE_RESP)
        self._codeRep = 99
        self._data = None
    
    def getCodeRep(self):
        """return response code as int"""
        return self._codeRep
    
    def setCodeRep(self,code):
        """code must be int"""
        self._codeRep = code
        
    def getData(self):
        return self._data
    
    def setData(self,data):
        self._data = data
        
    def getSerializeNoSign(self):
        return "%d;%s;%d;%s"%(self.getType(),self.getSenderID(),self.getCodeRep(),self.getData())
        
    